package com.seguriapp.listener;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.servlet.ServletContext;

import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.java.annotation.ServerAnnotationProcessor;
import org.cometd.server.BayeuxServerImpl;
import org.cometd.server.transport.JSONPTransport;
import org.cometd.server.transport.JSONTransport;
import org.cometd.websocket.server.WebSocketTransport;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;

/**
 * Bayeux Service Initializer
 * 
 * @author Tania Gonzales(taniadgv@gmail.com)
 */
@Component
public class BayeuxInitializer implements DestructionAwareBeanPostProcessor, ServletContextAware {

  private BayeuxServer bayeuxServer;
  private ServerAnnotationProcessor processor;

  @Inject
  public void setBayeuxServer(BayeuxServer bayeuxServer) {
    this.bayeuxServer = bayeuxServer;
  }

  @PostConstruct
  public void init() {
    this.processor = new ServerAnnotationProcessor(bayeuxServer);
  }

  @PreDestroy
  public void destroy() {
  }

  public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
    processor.processDependencies(bean);
    processor.processConfigurations(bean);
    processor.processCallbacks(bean);
    return bean;
  }

  public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
    return bean;
  }

  public void postProcessBeforeDestruction(Object bean, String name) throws BeansException {
    processor.deprocessCallbacks(bean);
  }

  @Bean(initMethod = "start", destroyMethod = "stop")
  public BayeuxServer bayeuxServer() {
    BayeuxServerImpl bean = new BayeuxServerImpl();
    bean.setTransports(new WebSocketTransport(bean), new JSONTransport(bean), new JSONPTransport(bean));
    return bean;
  }

  public void setServletContext(ServletContext servletContext) {
    servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
  }
}
